﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using Kinect.Framework.Interfaces;
using Kinect.Framework.Lib;
using ManagedNite;

namespace Kinect.Framework.Controls
{
    public class KinectButton : Button, IKinectElement
    {
        #region Events GotKinectFocused
        public delegate void GotKinectFocusedEventHandler(object s, PayloadEventArgs<IKinectElement> e);
        public event GotKinectFocusedEventHandler GotKinectFocused;
        public void OnGotKinectFocused(IKinectElement value)
        {
            if (GotKinectFocused != null)
                GotKinectFocused(this, new PayloadEventArgs<IKinectElement>(value));
        }
        #endregion

        #region Events LostKinectFocused
        public delegate void LostKinectFocusedEventHandler(object s, PayloadEventArgs<IKinectElement> e);
        public event LostKinectFocusedEventHandler LostKinectFocused;
        public void OnLostKinectFocused(IKinectElement value)
        {
            if (LostKinectFocused != null)
                LostKinectFocused(this, new PayloadEventArgs<IKinectElement>(value));
        }
        #endregion

        static KinectButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(KinectButton), new FrameworkPropertyMetadata(typeof(KinectButton)));
        }

        #region Fields and simple properties

        // These constants are the same as the built-in effects
        /// <summary>
        /// Maximum amount of tilt, in radians
        /// </summary>
        const double MaxAngle = 0.3;

        /// <summary>
        /// Maximum amount of depression, in pixels
        /// </summary>
        const double MaxDepression = 25;

        /// <summary>
        /// Delay between releasing an element and the tilt release animation playing
        /// </summary>
        public readonly TimeSpan TiltReturnAnimationDelay = TimeSpan.FromMilliseconds(200);

        /// <summary>
        /// Duration of tilt release animation
        /// </summary>
        public readonly TimeSpan TiltReturnAnimationDuration = TimeSpan.FromMilliseconds(100);

        /// <summary>
        /// The control that is currently being tilted
        /// </summary>
        public FrameworkElement currentTiltElement;

        /// <summary>
        /// The single instance of a storyboard used for all tilts
        /// </summary>
        public Storyboard tiltReturnStoryboard;

        /// <summary>
        /// The single instance of an X rotation used for all tilts
        /// </summary>
        public DoubleAnimation tiltReturnXAnimation;

        /// <summary>
        /// The single instance of a Y rotation used for all tilts
        /// </summary>
        public DoubleAnimation tiltReturnYAnimation;

        /// <summary>
        /// The single instance of a Z depression used for all tilts
        /// </summary>
        public DoubleAnimation tiltReturnZAnimation;

        /// <summary>
        /// The center of the tilt element
        /// </summary>
        public Point currentTiltElementCenter;

        /// <summary>
        /// Whether the animation just completed was for a 'pause' or not
        /// </summary>
        public bool wasPauseAnimation = false;

        /// <summary>
        /// Whether to use a slightly more accurate (but slightly slower) tilt animation easing function
        /// </summary>
        public bool UseLogarithmicEase { get; set; }

        /// <summary>
        /// Default list of items that are tiltable
        /// </summary>
        public List<Type> TiltableItems { get; private set; }

        #endregion

        //private DispatcherTimer Timer;
        public XnMPoint LastTouchPoint = new XnMPoint();
        public XnMPoint LastRealTouchPoint = new XnMPoint();

        #region IKinectElement Members

        public virtual void GotKinectFocus(XnMPoint point, XnMPoint realPoint, UIElement OriginalSource)
        {
            LastTouchPoint = point;
            LastRealTouchPoint = realPoint;
            OnGotKinectFocused(this);

        }
        public virtual void LostKinectFocus()
        {
            LastTouchPoint = null;
            LastRealTouchPoint = null;
            OnLostKinectFocused(this);
        }

        #endregion

        public KinectButton()
        {

        }
    }
}
